
/**
 * AppleIIGo
 * Disk II Controller class
 * (C) 2007-2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#ifndef DiskIIController_H
#define DiskIIController_H

#include "SlotDevice.h"
#include "DiskPort.h"

#define SEQUENCERREGISTER_SHIFT		(0 << 0)
#define SEQUENCERREGISTER_LOAD		(1 << 0)
#define SEQUENCERREGISTER_READ		(0 << 1)
#define SEQUENCERREGISTER_WRITE		(1 << 1)

typedef enum {
	SEQUENCERSTATE_OTHER,
	SEQUENCERSTATE_BIT6,
	SEQUENCERSTATE_QAWAIT,
};

typedef enum {
	DISKPORT_DRIVE5_25_1,
	DISKPORT_DRIVE5_25_2,
	DISKPORT_DRIVE3_5_1,
	DISKPORT_DRIVE3_5_2,
	DISKPORT_SMARTPORT,
	DISKPORT_END,
};

class DiskIIController : public SlotDevice {
public:
	DiskIIController(class Motherboard * motherboard, char * slotDeviceName);
	virtual ~DiskIIController();
	
	void onResetAsserted(bool isRestart);
	void onFrameEnd();
	
	void writeIo(UINT16 address, UINT8 value);
	UINT8 readIo(UINT16 address);
	
protected:
	class List * diskDrives;
	
	bool isDiskIIController;
	class DiskPort * diskPort[DISKPORT_END];
	class DiskPort * selectedPort;
	
	UINT32 motorOffFrameIndex;
	
	UINT8 phaseRegister;
	UINT64 lastPhaseQ3ClockIndex;
	bool isPhaseRegisterUpdated;
	bool isDriveEnabled;
	bool isDrive2Value;
	UINT8 sequencerRegister;
	UINT32 sequencerState;
	UINT8 shiftRegister;
	UINT64 lastSequencerQ3ClockIndex;
	
	bool isLatchMode;
	bool isAsynchronousMode;
	bool isDriveTimerEnabled;
	UINT32 bitCellShift;
	bool isDrive35Enabled;
	bool isWriteDataReady;
	bool isWriteUnderrun;
	UINT8 readDataRegister;
	UINT8 writeDataRegister;
	UINT32 writeDataBitNum;
	
	virtual void connectDrives(char * driveList[]);
	virtual void connectDrive(char * driveType);
	virtual void updateSelectedPort();
	
	void setPhase(UINT32 index, bool value);
	void setDriveEnable(bool value);
	void setDrive2(bool value);
	void setSequencer(UINT32 index, bool value);
	
	void updateState();
	
	virtual UINT8 setRegister(UINT8 value);
};

#endif
